﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.UI;
using Newtonsoft.Json;

// ReSharper disable once CheckNamespace
namespace com.kmer.Helper {
	/// <summary>
	/// Cookie操作类
	/// </summary>
	public static class CookiesHelper {

		#region SET VALUE

		#region HttpContext

		#region SET T
		public static void SetCookie<T>(this HttpContext context, string name, string key, T value) where T : struct {
			context.Response.SetCookie(name, key, value, null);
		}
		public static void SetCookie<T>(this HttpContext context, string name, string key, T value, DateTime expires) where T : struct {
			context.Response.SetCookie(name, key, value, expires);
		}
		public static void SetCookie<T>(this HttpContext context, string key, T value) where T : struct {
			context.Response.SetCookie(key, null, value, null);
		}
		public static void SetCookie<T>(this HttpContext context, string key, T value, DateTime expires) where T : struct {
			context.Response.SetCookie(key, null, value, expires);
		}
		#endregion

		#region SET string

	    public static void SetCookie(string name, string value, DateTime expires)
	    {
	        HttpContext.Current.SetCookie(name,value, expires);
	    }
		public static void SetCookie(this HttpContext context, string name, string key, string value) {
			context.Response.SetCookie(name, key, value, null);
		}
		public static void SetCookie(this HttpContext context, string name, string key, string value, DateTime expires)  {
			context.Response.SetCookie(name, key, value, expires);
		}
		public static void SetCookie(this HttpContext context, string key, string value)  {
			context.Response.SetCookie(key, null, value, null);
		}
		public static void SetCookie(this HttpContext context, string key, string value, DateTime expires) {
			context.Response.SetCookie(key, null, value, expires);
		}
		#endregion

		#endregion

		#region System.Web.UI.MasterPage

		#region SET T
		/// <summary>
		/// 设置Cookie
		/// </summary>
		/// <typeparam name="T">结构（struct）类型的值 比如 int</typeparam>
		/// <param name="masterPage"></param>
		/// <param name="name"></param>
		/// <param name="key"></param>
		/// <param name="value"></param>
		public static void SetCookie<T>(this System.Web.UI.MasterPage masterPage, string name, string key, T value) where T : struct {
			masterPage.Response.SetCookie(name, key, value, null);
		}
		/// <summary>
		/// 设置Cookie
		/// </summary>
		/// <typeparam name="T">结构（struct）类型的值 比如 int</typeparam>
		/// <param name="masterPage"></param>
		/// <param name="key"></param>
		/// <param name="value"></param>
		public static void SetCookie<T>(this System.Web.UI.MasterPage masterPage, string key, T value) where T : struct {
			masterPage.Response.SetCookie(key, null, value, null);
		}
		/// <summary>
		/// 设置Cookie
		/// </summary>
		/// <typeparam name="T">结构（struct）类型的值 比如 int</typeparam>
		/// <param name="masterPage"></param>
		/// <param name="name"></param>
		/// <param name="key"></param>
		/// <param name="value"></param>
		/// <param name="expires"></param>
		public static void SetCookie<T>(this System.Web.UI.MasterPage masterPage, string name, string key, T value, DateTime expires) where T : struct {
			masterPage.Response.SetCookie(name, key, value, expires);
		}
		/// <summary>
		/// 设置Cookie
		/// </summary>
		/// <typeparam name="T">结构（struct）类型的值 比如 int</typeparam>
		/// <param name="masterPage"></param>
		/// <param name="key"></param>
		/// <param name="value"></param>
		/// <param name="expires"></param>
		public static void SetCookie<T>(this System.Web.UI.MasterPage masterPage, string key, T value, DateTime expires) where T : struct {
			masterPage.Response.SetCookie(key, null, value, expires);
		}
		#endregion

		#region SET string
		/// <summary>
		/// 设置Cookie
		/// </summary>
		/// <typeparam name="T">结构（struct）类型的值 比如 int</typeparam>
		/// <param name="masterPage"></param>
		/// <param name="name"></param>
		/// <param name="key"></param>
		/// <param name="value"></param>
		public static void SetCookie(this System.Web.UI.MasterPage masterPage, string name, string key, string value) {
			masterPage.Response.SetCookie(name, key, value, null);
		}
		/// <summary>
		/// 设置Cookie
		/// </summary>
		/// <typeparam name="T">结构（struct）类型的值 比如 int</typeparam>
		/// <param name="masterPage"></param>
		/// <param name="key"></param>
		/// <param name="value"></param>
		public static void SetCookie(this System.Web.UI.MasterPage masterPage, string key, string value) {
			masterPage.Response.SetCookie(key, null, value, null);
		}
		/// <summary>
		/// 设置Cookie
		/// </summary>
		/// <typeparam name="T">结构（struct）类型的值 比如 int</typeparam>
		/// <param name="masterPage"></param>
		/// <param name="name"></param>
		/// <param name="key"></param>
		/// <param name="value"></param>
		/// <param name="expires"></param>
		public static void SetCookie(this System.Web.UI.MasterPage masterPage, string name, string key, string value, DateTime expires) {
			masterPage.Response.SetCookie(name, key, value, expires);
		}
		/// <summary>
		/// 设置Cookie
		/// </summary>
		/// <typeparam name="T">结构（struct）类型的值 比如 int</typeparam>
		/// <param name="masterPage"></param>
		/// <param name="key"></param>
		/// <param name="value"></param>
		/// <param name="expires"></param>
		public static void SetCookie(this System.Web.UI.MasterPage masterPage, string key, string value, DateTime expires)  {
			masterPage.Response.SetCookie(key, null, value, expires);
		}
		#endregion

		#endregion

		#region System.Web.UI.Page

		#region SET T
		public static void SetCookie<T>(this Page page, string name, string key, T value) where T : struct {
			page.Response.SetCookie(name, key, value, null);
		}
		public static void SetCookie<T>(this Page page, string name, string key, T value, DateTime expires) where T : struct {
			page.Response.SetCookie(name, key, value, expires);
		}

		/// <summary>
		/// 设置Cookie
		/// </summary>
		/// <typeparam name="T">结构（struct）类型的值 比如 int</typeparam>
		/// <param name="page"></param>
		/// <param name="key"></param>
		/// <param name="value"></param>
		public static void SetCookie<T>(this Page page, string key, T value) where T:struct {
			page.Response.SetCookie(key, null, value, null);
		}
		public static void SetCookie<T>(this Page page, string key, T value, DateTime expires) where T : struct {
			page.Response.SetCookie(key, null, value, expires);
		}
		#endregion

		#region SET string
		public static void SetCookie(this Page page, string name, string key, string value)  {
			page.Response.SetCookie(name, key, value, null);
		}
		public static void SetCookie(this Page page, string name, string key, string value, DateTime expires)  {
			page.Response.SetCookie(name, key, value, expires);
		}

		/// <summary>
		/// 设置Cookie
		/// </summary>
		/// <typeparam name="T">结构（struct）类型的值 比如 int</typeparam>
		/// <param name="page"></param>
		/// <param name="key"></param>
		/// <param name="value"></param>
		public static void SetCookie(this Page page, string key, string value){
			page.Response.SetCookie(key, null, value, null);
		}
		public static void SetCookie(this Page page, string key, string value, DateTime expires)  {
			page.Response.SetCookie(key, null, value, expires);
		}
		#endregion

		#endregion

		#region SET T
		/// <summary>
		/// 设置Cookie
		/// </summary>
		/// <typeparam name="T">结构（struct）类型的值 比如 int</typeparam>
		/// <param name="response"></param>
		/// <param name="key">关键字</param>
		/// <param name="value">值</param>
		public static void SetCookie<T>(this HttpResponse response, string key, T value) where T:struct {
			response.SetCookie(key, null, value, null);
		}
		/// <summary>
		/// 设置Cookie
		/// </summary>
		/// <typeparam name="T">结构（struct）类型的值 比如 int</typeparam>
		/// <param name="response"></param>
		/// <param name="key"></param>
		/// <param name="value"></param>
		/// <param name="expires"></param>
		public static void SetCookie<T>(this HttpResponse response, string key, T value, DateTime expires) where T:struct {
			response.SetCookie(key, null, value, expires);
		}
		/// <summary>
		/// 设置Cookie
		/// </summary>
		/// <typeparam name="T">结构（struct）类型的值 比如 int</typeparam>
		/// <param name="response"></param>
		/// <param name="name"></param>
		/// <param name="key"></param>
		/// <param name="value"></param>
		public static void SetCookie<T>(this HttpResponse response, string name, string key, T value) where T : struct{
			response.SetCookie(name, key, value.ToString(), null);
		}
		/// <summary>
		/// 设置Cookie
		/// </summary>
		/// <typeparam name="T">结构（struct）类型的值 比如 int</typeparam>
		/// <param name="response"></param>
		/// <param name="name"></param>
		/// <param name="key"></param>
		/// <param name="value"></param>
		/// <param name="expires"></param>
		public static void SetCookie<T>(this HttpResponse response, string name, string key, T value, DateTime? expires)
			where T:struct
		{
			response.SetCookie(name, key, value.ToString(), expires);
		}
		#endregion

		#region SET string
		public static void SetCookie(this HttpResponse response, string key, string value) {
			response.SetCookie(key, null, value, null);
		}
		public static void SetCookie(this HttpResponse response, string key, string value, DateTime? expires) {
			response.SetCookie(key, null, value, expires);
		}
		public static void SetCookie(this HttpResponse response, string name, string key, string value){
			response.SetCookie(name, key, value, null);
		}
		
        public static void SetCookie(this HttpResponse response, string name, string key, string value, DateTime? expires){
			var cookie = response.Cookies[name];
			if (cookie == null) return;
			if (!string.IsNullOrEmpty(key) && cookie.HasKeys)
				cookie.Values.Set(key, value);
			else
				if (!string.IsNullOrEmpty(value))
				cookie.Value = value;
			if (expires != null)
				cookie.Expires = expires.Value;
			response.SetCookie(cookie);
		}
		#endregion

		#endregion

		#region GET VALUE

		#region GET string
		public static string GetCookie(this HttpContext context, string name, string key, string dv) {
			return context.Request.GetCookie(name, key, dv);
		}
		public static string GetCookie(this HttpContext context, string key, string dv) {
			return context.Request.GetCookie(key, null, dv);
		}
		public static string GetCookie(this HttpContext context, string key) {
			return context.Request.GetCookie(key, null, string.Empty);
		}

		public static string GetCookie(this Page page, string name, string key, string dv) {
			return page.Request.GetCookie(name, key, dv);
		}
		public static string GetCookie(this Page page, string key, string dv) {
			return page.Request.GetCookie(key, null, dv);
		}
		public static string GetCookie(this Page page, string key) {
			return page.Request.GetCookie(key, null, string.Empty);
		}
		public static string GetCookie(this HttpRequest request, string name, string key, string dv) {
			if (!request.Cookies.AllKeys.Contains(name)) return dv;
			var cookie = request.Cookies[name];
			return Get(cookie, key, dv);
		}

	    public static string GetCookieValue(string name)
	    {
	        return HttpContext.Current.Request.GetCookie(name);
	    }
        public static int GetCookieValue(string name, int dv) {
            var r= HttpContext.Current.Request.GetCookie(name);
            if (string.IsNullOrWhiteSpace(r)) return dv;
            var ri = 0;
            return int.TryParse(r, out ri) ? ri : dv;
        }
        public static string GetCookie(this HttpRequest request, string key, string dv) {
			return request.GetCookie(key, null, dv);
		}
		public static string GetCookie(this HttpRequest request, string key) {
			return request.GetCookie(key, null, string.Empty);
		}
		#endregion

		#region Get T

		public static T GetCookie<T>(this HttpRequest request, string name, string key, T dv) where T : struct {
			if (!request.Cookies.AllKeys.Contains(name)) return dv;
			var cookie = request.Cookies[name];
			return Get(cookie, key, dv);
		}
		public static T GetCookie<T>(this HttpRequest request, string key, T dv) where T : struct {
			return request.GetCookie(key, null, dv);
		}
		public static T GetCookie<T>(this Page page, string name, string key, T dv) where T : struct {
			return page.Request.GetCookie(name, key, dv);
		}
		public static T GetCookie<T>(this Page page, string key, T dv) where T : struct {
			return page.Request.GetCookie(key,null, dv);
		}
		static T Get<T>(HttpCookie cookie, string key, T dv ) where T:struct {
			var r = Get(cookie, key, string.Empty);
			var converter = TypeDescriptor.GetConverter(dv.GetType());
			if (!converter.CanConvertFrom(typeof (string))) return dv;
			if (string.IsNullOrWhiteSpace(r)) return dv;
			var rr = converter.ConvertFrom(r);
			return rr == null ? dv : (T)rr;
		}
		#endregion

		static string Get(HttpCookie cookie, string key, string dv) {
			if (!cookie.HasKeys)
				return string.IsNullOrWhiteSpace(cookie.Value) ? dv : cookie.Value;
			if (string.IsNullOrWhiteSpace(key)) {
				return dv;
			}
			var r = cookie.Values[key];
			if (string.IsNullOrWhiteSpace(r)) return dv;
			return string.IsNullOrWhiteSpace(cookie.Value) ? dv : cookie.Value;
		}

		#endregion

		#region Remove
		public static void RemoveCookie(this Page page, string name){
			page.Response.RemoveCookie(name);
		}
        
		public static void RemoveCookie(this Page page, string name, string key){
			page.Response.RemoveCookie(name, key);
		}
		public static void RemoveCookie(this HttpResponse response, string name) {
			response.RemoveCookie(name, null);
		}
		public static void RemoveCookie(this HttpResponse response, string name, string key) {
			var cookie = response.Cookies[name];
			if (cookie == null) return;
			if (!string.IsNullOrEmpty(key) && cookie.HasKeys)
				cookie.Values.Remove(key);
			else
				response.Cookies.Remove(name);
		}
		#endregion
	}
}
